﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using Sok.Munkae.Util;

namespace Sok.Munkae.Data
{
    public interface IDao<T>
    {
        IList<T> GetList(string query, Dictionary<string, object> commandParameters,
                         Func<SqlDataReader, IList<T>> listBuilderDelegate);

        T GetOne(string query, Dictionary<string, object> commandParameters,
                 Func<SqlDataReader, T> objectBuilderDelegate);
    }

    public class Dao<T> : IDao<T>
    {
        private SQLHelper sql;
        private string strConnectionString = string.Empty;

        public Dao()
        {
            sql = new SQLHelper();
        }

        #region IDao<T> Members

        public IList<T> GetList(string query, Dictionary<string, object> commandParameters,
                                Func<SqlDataReader, IList<T>> listBuilderDelegate)
        {
            return ExecuteReader(query, commandParameters, listBuilderDelegate);
        }

        public T GetOne(string query, Dictionary<string, object> commandParameters,
                        Func<SqlDataReader, T> objectBuilderDelegate)
        {
            return ExecuteReader(query, commandParameters, objectBuilderDelegate);
        }

        #endregion

        public SqlConnection connection()
        {
            var con =
                new SqlConnection(
                    ConfigurationManager.ConnectionStrings["SokMunkaeDemoConnectionString"].ConnectionString);
            con.Open();
            return con;
        }

        private IList<T> ExecuteReader(string query, Dictionary<string, object> commandParameters,
                                       Func<SqlDataReader, IList<T>> listBuilderDelegate)
        {
            using (SqlConnection con = connection())
            {
                SqlDataReader dr = GetDataReader(query, con, commandParameters);
                return listBuilderDelegate(dr);
            }
        }

        private T ExecuteReader(string query, Dictionary<string, object> commandParameters,
                                Func<SqlDataReader, T> objectBuilderDelegate)
        {
            using (SqlConnection con = connection())
            {
                SqlDataReader dr = GetDataReader(query, con, commandParameters);
                return objectBuilderDelegate(dr);
            }
        }

        private SqlDataReader GetDataReader(string query, SqlConnection con,
                                            Dictionary<string, object> commandParameters)
        {
            var cmd = new SqlCommand(query, con);
            foreach (var p in commandParameters)
            {
                cmd.Parameters.Add(p.Key, p.Value);
            }
            return cmd.ExecuteReader();
        }
    }
}